// noinspection DuplicatedCode

import { BrowserWindow, BrowserView, ipcMain, webContents } from 'electron';
import { getRenderContentUrl } from '../config/run';
import { showSkeletonScreen } from './showSkeletonScreen';
import path from 'path';

export function initWorkbenchApplicationIpcMain() {
  ipcMain.on('sendMain__workbenchApplicationWindow_sendAppInfo', (event, appInfo) => {
    handleWorkbenchApplicationWindow(appInfo);
  });
}

export function createCurrentWindowEventListeners() {
  // 切换应用
  ipcMain.on(
    'sendMain__workbenchApplicationWindow_changeApp',
    handleWorkbenchApplicationWindowAppChange,
  );

  // 刷新应用
  ipcMain.on(
    'sendMain__workbenchApplicationWindow_reloadApp',
    handleWorkbenchApplicationWindowReloadApp,
  );

  // 打开调试（应用的调试）
  ipcMain.on(
    'sendMain__workbenchApplicationWindow_openDevtools',
    handleWorkbenchApplicationWindowOpenDevtools,
  );

  // 删除应用
  ipcMain.handle(
    'sendMain__workbenchApplicationWindow_remoteApp',
    handleWorkbenchApplicationWindowRemoveApp,
  );
}

export function remoteIpcMainEventListeners() {
  ipcMain.removeListener(
    'sendMain__workbenchApplicationWindow_changeApp',
    handleWorkbenchApplicationWindowAppChange,
  );
  ipcMain.removeListener(
    'sendMain__workbenchApplicationWindow_reloadApp',
    handleWorkbenchApplicationWindowReloadApp,
  );

  ipcMain.removeListener(
    'sendMain__workbenchApplicationWindow_openDevtools',
    handleWorkbenchApplicationWindowOpenDevtools,
  );

  // ipcMain.removeListener(
  //   'sendMain__workbenchApplicationWindow_remoteApp',
  //   handleWorkbenchApplicationWindowRemoveApp,
  // );

  ipcMain.removeHandler('sendMain__workbenchApplicationWindow_remoteApp');
}

let workbenchApplicationWindow;

export function getWindow() {
  return workbenchApplicationWindow;
}

export function destroyWindow() {
  remoteIpcMainEventListeners();
  workbenchApplicationWindow = null;
}

function destroyView(key, map = workbenchApplicationWindow.browserViewMap) {
  const value = map.get(key);
  if (!value) {
    return;
  }
  value.webContents.destroy();
  workbenchApplicationWindow.removeBrowserView(value);
  map.set(key, null);
  map.delete(key);
}

function destroyAllView() {
  let map = workbenchApplicationWindow.browserViewMap;
  map.forEach((view, key) => {
    destroyView(key, map);
  });
  map.clear();
  workbenchApplicationWindow.setBrowserView(null);
  workbenchApplicationWindow.browserViewMap = null;
  map = null;
  workbenchApplicationWindow.browserViewId = null;
}

async function createWindow() {
  createCurrentWindowEventListeners();
  workbenchApplicationWindow = new BrowserWindow({
    width: 1200,
    height: 900,
    webPreferences: {
      // 禁用 remote 模块，默认为false 禁用
      enableRemoteModule: true,
      // 是否启用nodejs，默认为false，禁用
      nodeIntegration: true,
      // 是否启用上下文隔离，在预加载脚本中通过window.xxx = xxx设置的值将失效
      // 默认为true，开启隔离
      contextIsolation: false,
      webSecurity: false,
      // preload: path.join(__dirname, 'multipleTabPreload.js'),
    },
  });
  workbenchApplicationWindow.on('close', event => {
    if (workbenchApplicationWindow.browserViewMap) {
      destroyAllView();
    }
  });
  workbenchApplicationWindow.on('closed', () => {
    destroyWindow();
  });
  await workbenchApplicationWindow.loadURL(getRenderContentUrl('/multiple-tab'));
  // await workbenchApplicationWindow.loadURL('http://192.168.91.69:8081/test.html');

  return workbenchApplicationWindow;
}

function sendOpenAppMessage(appInfo, data) {
  workbenchApplicationWindow.webContents.send(
    'sendRenderer__workbenchApplicationWindow_openAppInfo',
    {
      data: {
        appInfo,
      },
    },
  );
  workbenchApplicationWindow.browserViewId = appInfo.id;
}

function createView(url) {
  const view = new BrowserView({
    webPreferences: {
      preload: path.join(__dirname, 'viewPreload.js'),
    },
  });
  workbenchApplicationWindow.setBrowserView(view);
  view.setBounds({ x: 0, y: 50, width: 1200, height: 820 });
  view.setAutoResize({
    width: true,
    height: true,
  });
  view.webContents.executeJavaScript(showSkeletonScreen(), true);
  view.webContents.on('did-finish-load', () => {});
  view.webContents.loadURL(url);
  return view;
}

// 打开应用
async function handleWorkbenchApplicationWindow(appInfo) {
  try {
    if (workbenchApplicationWindow) {
      workbenchApplicationWindow.show();
    } else {
      await createWindow();
    }

    let browserViewMap = workbenchApplicationWindow.browserViewMap;
    if (!browserViewMap) {
      browserViewMap = workbenchApplicationWindow.browserViewMap = new Map();
    }
    let browserViewInfo = browserViewMap.get(appInfo.id);

    if (browserViewInfo) {
      if (workbenchApplicationWindow.browserViewId === appInfo.id) {
        console.log('激活已经激活的应用，将终止后续代码执行');
        return;
      }
      workbenchApplicationWindow.setBrowserView(browserViewInfo);
      sendOpenAppMessage(appInfo);
      return;
    }
    const view = createView(appInfo.loadUrl);
    browserViewMap.set(appInfo.id, view);
    sendOpenAppMessage(appInfo);
  } catch (error) {
    console.log('handleWorkbenchApplicationWindow catch error >>> ', error);
  }
}

function handleWorkbenchApplicationWindowAppChange(event, appId) {
  try {
    const browserView = workbenchApplicationWindow.browserViewMap.get(appId);
    workbenchApplicationWindow.setBrowserView(browserView);
    workbenchApplicationWindow.browserViewId = appId;
  } catch (error) {
    console.log('handleWorkbenchApplicationWindowAppChange catch error >>> ', error);
  }
}

function handleWorkbenchApplicationWindowReloadApp(event, appId) {
  try {
    const browserView = workbenchApplicationWindow.browserViewMap.get(appId);
    browserView.webContents.reload();
  } catch (error) {
    console.log('handleWorkbenchApplicationWindowReloadApp catch error >>> ', error);
  }
}

function handleWorkbenchApplicationWindowOpenDevtools(event, appId) {
  try {
    const browserView = workbenchApplicationWindow.browserViewMap.get(appId);
    browserView.webContents.openDevTools();
  } catch (error) {
    console.log('handleWorkbenchApplicationWindowOpenDevtools catch error >>> ', error);
  }
}

function handleWorkbenchApplicationWindowRemoveApp(event, appId) {
  try {
    const view = workbenchApplicationWindow.browserViewMap.get(appId);
    if (!view) {
      return Promise.resolve(false);
    }
    destroyView(appId);
    if (workbenchApplicationWindow.browserViewMap.size === 0) {
      workbenchApplicationWindow.close();
    }
    return Promise.resolve(true);
  } catch (error) {
    console.log('handleWorkbenchApplicationWindowRemoveApp catch error >>> ', error);
  }
  return Promise.resolve(false);
}

/**
 * 如何在 Electron 中隐藏（而不是破坏）BrowserView
 * https://stackoverflow.com/questions/56564344/how-to-hide-not-destroy-a-browserview-in-electron
 *
 * Electron - 如何复制 BrowserWindow？
 * https://stackoverflow.com/questions/65854643/electron-how-to-duplicate-a-browserwindow/65862263#65862263
 *
 * How to use sqlite3 module with electron?
 * https://stackoverflow.com/questions/32504307/how-to-use-sqlite3-module-with-electron
 */
